﻿using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace Common
{
    public static class FileHelper
    {
        public static string CalculateFileHash(string filePath)
        {
            using (var md5 = MD5.Create())
            using (var stream = File.OpenRead(filePath))
            {
                var hash = md5.ComputeHash(stream);
                return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
            }
        }

        //public static async Task<string> CalculateFileHashAsync(string filePath)
        //{
        //    using (var md5 = MD5.Create())
        //    using (var stream = File.OpenRead(filePath))
        //    {
        //        var hash = await md5.ComputeHashAsync(stream);
        //        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        //    }
        //}
        // 获取唯一文件路径的方法
        public static string GetUniqueFilePath(string directory, string fileName)
        {
            string baseName = Path.GetFileNameWithoutExtension(fileName);
            string extension = Path.GetExtension(fileName);
            string path = Path.Combine(directory, fileName);

            // 如果文件不存在，直接返回原路径
            if (!File.Exists(path))
            {
                return path;
            }

            // 文件已存在，添加序号
            int counter = 1;
            while (true)
            {
                string newFileName = $"{baseName}({counter}){extension}";
                string newPath = Path.Combine(directory, newFileName);

                if (!File.Exists(newPath))
                {
                    return newPath;
                }

                counter++;
            }
        }

        public static async Task<string> CalculateFileHashAsync(string filePath, int bufferSize = 81920 /* 默认缓冲区大小 */, CancellationToken cancellationToken = default)
        {
            using (var md5 = MD5.Create())
            {
                // 使用带有异步选项和优化缓冲区大小的FileStream
                using (var stream = new FileStream(
                    filePath,
                    FileMode.Open,
                    FileAccess.Read,
                    FileShare.Read,
                    bufferSize: bufferSize,
                    options: FileOptions.SequentialScan | FileOptions.Asynchronous))
                {
                    var hash = await md5.ComputeHashAsync(stream, cancellationToken)
                                       .ConfigureAwait(false);
                    return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
                }
            }
        }
        // 快速文件标识（前1MB哈希 + 文件大小）
        public static async Task<string> GetQuickFileIdentity(string filePath)
        {
            const int sampleSize = 1 * 1024 * 1024; // 1MB
            var fileInfo = new FileInfo(filePath);
            long fileSize = fileInfo.Length;

            using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[Math.Min(sampleSize, fileSize)];
                int bytesRead = await fs.ReadAsync(buffer, 0, buffer.Length);

                using (var sha = SHA256.Create())
                {
                    byte[] hashBytes = sha.ComputeHash(buffer);
                    return $"{fileSize}-{BitConverter.ToString(hashBytes).Replace("-", "")}";
                }
            }
        }
    }
}